using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization;
using System.IO;
using MIMPGameLibrary;

namespace MIMPWinForms.Forms
{
    public partial class MainMenuForm : Form
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        /// <summary>
        /// Occurs when the user clicks the ExitGame button on the Main Menu.
        /// </summary>
        public event CancelEventHandler ExitGame;
        /// <summary>
        /// Occurs when a new game should be loaded from the GameState in the EventArgs.
        /// </summary>
        public event EventHandler<EventArgs<GameState>> LoadGame;

        protected virtual void RaiseExitGame() {
            if (ExitGame != null) {
                if (log.IsInfoEnabled) log.Info("Raising ExitGame");
                ExitGame(this, new CancelEventArgs());
            }
        }

        protected virtual void RaiseLoadGame(GameState toLoad) {
            if (LoadGame != null) {
                if (log.IsInfoEnabled) log.Info("Raising LoadGame");
                LoadGame(this, new EventArgs<GameState>(toLoad));
            }
        }

        private MapSetupForm setup;
        private bool isGameInProgress = false;
        /// <summary>
        /// The Main Menu has slightly different functionality depending on whether a game is currently in progress
        /// or not. Set this property when appropriate to ensure that the Main Menu displays the appropriate buttons.
        /// </summary>
        public bool IsGameInProgress {
            get { return isGameInProgress; }
            set { isGameInProgress = value; }
        }

        public MainMenuForm() {
            InitializeComponent();
            this.VisibleChanged += new EventHandler(MainMenuForm_VisibleChanged);
        }

        /// <summary>
        /// When the Main Menu becomes visible, change its appearance and functionality 
        /// to match the appropriate context: a game in progress, or no game in progress.
        /// </summary>
        void MainMenuForm_VisibleChanged(object sender, EventArgs e) {
            if (log.IsInfoEnabled) log.Info("Entered MainMenuForm_VisibleChanged");
            if (this.Visible) {
                if (log.IsDebugEnabled) log.Debug("Main menu is visible, IsGameInProgress is: " + IsGameInProgress);
                mnubtnNewGame.Enabled = !IsGameInProgress;
                mnubtnReturn.Enabled = IsGameInProgress;
                mnubtnSaveGame.Enabled = IsGameInProgress;
                this.Text = IsGameInProgress ? "Main Menu" : "MIMP";
                //this.ShowInTaskbar = !IsGameInProgress;
            }
            if (log.IsInfoEnabled) log.Info("Exiting MainMenuForm_VisibleChanged");
        }

        private void mnubtnNewGame_Click(object sender, EventArgs e) {
            if (log.IsInfoEnabled) log.Info("Entered mnubtnNewGame_Click");
            setup = new MapSetupForm(Constants.MAPS_DIRECTORY);
            setup.LoadGame += new EventHandler<EventArgs<GameState>>(setup_LoadGame);
            if (log.IsInfoEnabled) log.Info("Showing new game setup form.");
            setup.ShowDialog();
            if (log.IsInfoEnabled) log.Info("Exiting mnubtnNewGame_Click");
        }

        void setup_LoadGame(object sender, EventArgs<GameState> e) {
            if (log.IsInfoEnabled) log.Info("Entered setup_LoadGame");
            setup.Close();
            RaiseLoadGame(e.EventData);
            if (log.IsInfoEnabled) log.Info("Exiting setup_LoadGame");
        }

        private void mnubtnExit_Click(object sender, EventArgs e) {
            if (log.IsInfoEnabled) log.Info("Entered mnubtnExit_Click");
            RaiseExitGame();
            if (log.IsInfoEnabled) log.Info("Exiting mnubtnExit_Click");
        }

        private void mnubtnLoadGame_Click(object sender, EventArgs e) {
            if (log.IsInfoEnabled) log.Info("Entered mnubtnLoadGame_Click");
            if (openFileDialog.ShowDialog() == DialogResult.OK) {
                if (log.IsDebugEnabled) log.Debug("User selected a save file: " + openFileDialog.FileName);
                IFormatter loadformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                Stream loadStream = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.None);
                if (log.IsDebugEnabled) log.Debug("Opened file stream.");
                GameState loadedGameState = (GameState)loadformatter.Deserialize(loadStream);
                if (log.IsInfoEnabled) log.Info("Loaded game state.");
                loadStream.Close();
                RaiseLoadGame(loadedGameState);
            }
            if (log.IsInfoEnabled) log.Info("Exiting mnubtnLoadGame_Click");
        }

        private void mnubtnSaveGame_Click(object sender, EventArgs e) {
            if (log.IsInfoEnabled) log.Info("Entered mnubtnSaveGame_Click");
            //if (saveFileDialog.ShowDialog() == DialogResult.OK) {
            //    if (log.IsDebugEnabled) log.Debug("User selected a file to save to: " + saveFileDialog.FileName);
            //    IFormatter saveFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            //    Stream saveStream = new FileStream(saveFileDialog.FileName, FileMode.Create, FileAccess.Write, FileShare.None);
            //    if (log.IsDebugEnabled) log.Debug("Opened file stream.");
            //    saveFormatter.Serialize(saveStream, 
            //}
            if (log.IsInfoEnabled) log.Info("Exiting mnubtnSaveGame_Click");
        }

        private void mnubtnReturn_Click(object sender, EventArgs e) {
            if (log.IsInfoEnabled) log.Info("Entered mnubtnReturn_Click");
            this.Hide();
            if (log.IsInfoEnabled) log.Info("Exiting mnubtnReturn_Click");
        }

        private void mnubtnHelp_Click(object sender, EventArgs e) {
            if (log.IsInfoEnabled) log.Info("Entered mnubtnHelp_Click");
            if (log.IsInfoEnabled) log.Info("Exiting mnubtnHelp_Click");
        }
    }
}